package com.jgp.security.service;

import com.jgp.security.pojo.PowerInfo;
import com.jgp.security.pojo.UserInfo;
import com.jgp.security.secmodel.SecInstitution;
import com.jgp.security.secmodel.SecResource;
import com.jgp.security.secmodel.SecRole;
import com.jgp.security.secmodel.SecUser;
import com.jgp.sys.model.Menu;
import com.jgp.sys.props.ClientPropBean;
import com.jgp.sys.service.MenuService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 项目   jgp-cloud-parent
 * 作者   loufei
 * 时间   2019-11-04
 */
@Service
public class SecPowerService {
    
    @Autowired
    private SecUserService userService;
    
    @Autowired
    private SecRoleResourceService roleResourceService;
    
    @Autowired
    private SecRoleUserService roleUserService;
    
    @Autowired
    private SecInstitutionUserService institutionUserService;
    
    @Autowired
    private SecInstitutionService institutionService;
    
    @Autowired
    private SecRoleService roleService;
    
    @Autowired
    private SecRoleMenuService roleMenuService;
    
    @Autowired
    private MenuService menuService;
    
    @Autowired
    private ClientPropBean clientPropBean;
    
    /**
     * 获取权限配置
     *
     * @param info 用户信息
     * @return
     */
    public PowerInfo queryPowerInfo(UserInfo info) {
        PowerInfo powerInfo = new PowerInfo();
        SecUser superAdmin = userService.getSuperAdmin();
        if(StringUtils.isNotBlank(clientPropBean.getId())){
            info.setClientId(clientPropBean.getId());
            info.setExcludeModels(clientPropBean.getExcludes());
        }
        if (superAdmin.getUsername().equals(info.getUsername())) {
            powerInfo.addResource("*:*");
            powerInfo.addRole("*:*");
        } else {
            List<Long> roleIds = info.getRoles().stream().map(SecRole::getId).collect(Collectors.toList());
            List<String> roles = roleIds.stream().map(String::valueOf).collect(Collectors.toList());
            List<String> resources = info.getResources().stream().map(SecResource::getAction).collect(Collectors.toList());
            powerInfo.addAllRoles(roles);
            powerInfo.addAllResource(resources);
        }
        return powerInfo;
    }
    
    /**
     * 用户信息
     * 包括角色、机构、资源
     * @param user 用户
     * @param endPointType 终端类型 PC MOBILE PAD 等
     * @return
     */
    public UserInfo packageUserInfo(SecUser user, String endPointType) {
        SecUser superAdmin = userService.getSuperAdmin();
        UserInfo info = new UserInfo();
        if(StringUtils.isNotBlank(clientPropBean.getId())){
            info.setClientId(clientPropBean.getId());
            info.setExcludeModels(clientPropBean.getExcludes());
        }
        info.setOpenId(user.getThirdOpenId());
        if (superAdmin.getUsername().equals(user.getUsername())) {
            info.setId(user.getId());
            info.setRealName(user.getRealName());
            info.setNickName(user.getNickName());
            info.setUsername(superAdmin.getUsername());
            info.setLocked(superAdmin.getLocked());
            info.setEncryptTime(user.getEncryptTime());
            List<Menu> menus = menuService.queryFull();
            info.setInstitutions(institutionService.queryTop());
            info.setMenus(menus);
        } else {
            info.setId(user.getId());
            info.setUsername(user.getUsername());
            info.setRealName(user.getRealName());
            info.setNickName(user.getNickName());
            info.setTel(user.getTel());
            info.setEmail(user.getEmail());
            info.setLocked(user.getLocked());
            info.setEncryptTime(user.getEncryptTime());
            List<SecRole> roles = roleUserService.queryRoles(user.getId());
            info.setRoles(roles);
            List<SecInstitution> institutions = institutionUserService.queryInstitutions(user.getId());
            info.setInstitutions(institutions);
            List<Menu> menus = roleMenuService.queryMenus(roles, endPointType, user.getType());
            info.setMenus(menus);
            List<SecResource> resources = roleResourceService.queryResources(roles);
            info.setResources(resources);
            info.setEndPointType(endPointType);
            List<SecInstitution> specialInstitutions = institutionService.querySpecialInstitutions(institutions);
            if(Objects.nonNull(specialInstitutions)&&specialInstitutions.size()>0){
                Map<String,SecInstitution> map = new HashMap<>();
                Map<String,List<SecInstitution>> map2 = new HashMap<>();
                for (SecInstitution specialInstitution : specialInstitutions) {
                    String specialTypeCode = specialInstitution.getSpecialTypeCode();
                    if(StringUtils.isNotBlank(specialTypeCode)){
                        map.put(specialTypeCode,specialInstitution);
                    }
                    if(Objects.isNull(map2.get(specialTypeCode))){
                        map2.put(specialTypeCode,new ArrayList<>());
                    }
                    List<SecInstitution> arr = map2.get(specialTypeCode);
                    arr.add(specialInstitution);
                }
                info.setSpecialInstitutionMap(map);
                info.setSInsAllMap(map2);
            }
        }
        return info;
    }
    
    public List<String> queryRowIdsByInstitutions(List<SecInstitution> institutions) {
        return institutionUserService.queryUserIds(institutions.stream().map(SecInstitution::getId).collect(Collectors.toList()));
    }
    
    public List<String> queryRowIdsByInstitutionsAndDown(List<SecInstitution> institutions) {
        List<Long> ids = institutions.stream().map(SecInstitution::getId).collect(Collectors.toList());
        List<SecInstitution> downInstitutions = institutionService.queryDown(institutions);
        List<Long> childIds = downInstitutions.stream().map(SecInstitution::getId).collect(Collectors.toList());
        ids.addAll(childIds);
        return institutionUserService.queryUserIds(ids);
    }
    
    public List<String> queryRowIdsByRoles(List<SecRole> roles) {
        return roleUserService.queryUserIds(roles.stream().map(SecRole::getId).collect(Collectors.toList()));
    }
    
    public List<String> queryRowIdsByRolesAndDown(List<SecRole> roles) {
        List<Long> ids = roles.stream().map(SecRole::getId).collect(Collectors.toList());
        List<SecRole> downRoles = roleService.queryDown(roles);
        List<Long> childIds = downRoles.stream().map(SecRole::getId).collect(Collectors.toList());
        ids.addAll(childIds);
        return roleUserService.queryUserIds(ids);
    }
    
    public List<String> queryRowIdsBySpecialInstitutionsAndDown(List<SecInstitution> secInstitutions) {
        List<SecInstitution> downInstitutions = institutionService.queryDown(secInstitutions);
        List<Long> ids = downInstitutions.stream().map(SecInstitution::getId).collect(Collectors.toList());
        ids.addAll(secInstitutions.stream().map(SecInstitution::getId).collect(Collectors.toList()));
        return institutionUserService.queryUserIds(ids.stream().distinct().collect(Collectors.toList()));
    }
   
}
